import { plugin } from '../../components/index.js'
import DropFactory from '../../model/DropFactory.js'
import DropPreview from '../../model/DropPreview.js'

/*
指令：
- #修仙测试掉落 <副本|秘境> <层级> <次数> [seed <数值>] [unique]
  - 示例： #修仙测试掉落 副本 10 3 seed 42 unique
  - 多次模拟，按类别列出本次掉落详情
- #修仙测试预览 <副本|秘境> <层级> <次数>
  - 示例： #修仙测试预览 秘境 9 5
  - 输出类别汇总与 Top5 高频条目，附最近一次详情

  */

export class DropTest extends plugin {
  constructor() {
    super({
      name: '修仙_掉落测试',
      dsc: '掉落模拟与预览',
      event: 'message',
      priority: 2000,
      rule: [
        { reg: '^#修仙测试掉落(.*)$', fnc: 'run' },
        { reg: '^#修仙测试预览(.*)$', fnc: 'preview' }
      ]
    })
  }

  parseArgs(str){
    const t = (str || '').trim().split(/\s+/).filter(Boolean)
    const source = (t[0] === '秘境' || t[0] === '副本') ? t[0] : '副本'
    const layer = parseInt(t[1] || '10')
    const times = parseInt(t[2] || '3')
    const seedIdx = t.findIndex(x=>x.toLowerCase()==='seed')
    let seed = seedIdx>=0 && t[seedIdx+1] ? parseInt(t[seedIdx+1]) : undefined
    if (seed === undefined && t[3] && /^\d+$/.test(t[3])) seed = parseInt(t[3])
    const unique = t.some(x=>x.toLowerCase()==='unique')
    return { source, layer, times, seed, unique }
  }

  async run(){
    const m = this.e.msg.match(/^#修仙测试掉落(.*)$/)
    const { source, layer, times, seed, unique } = this.parseArgs(m ? m[1] : '')
    const lines = []
    lines.push(`来源:${source} 层级:${layer} 次数:${times} ${seed!==undefined?`seed:${seed}`:''} ${unique?'unique':''}`)
    for (let i=0;i<times;i++){
      const r = await DropFactory.drop(source, layer, { seed, unique, includeDebug: true })
      lines.push(`第${i+1}次:`)
      if (r.debug){
        lines.push(`  调试: layerName=${r.debug.layerName} total=${r.debug.total}`)
        lines.push(`  候选数: ${Object.entries(r.debug.candidateCounts).map(([k,v])=>`${k}:${v}`).join(' | ')} | 全部:${r.debug.layerPoolCount}`)
        lines.push(`  非零权重: ${Object.entries(r.debug.nonZeroWeightCounts||{}).map(([k,v])=>`${k}:${v}`).join(' | ')}`)
        lines.push(`  来源匹配: exact=${r.debug.matchBySource?.exact||0} alt=${r.debug.matchBySource?.alt||0}`)
        lines.push(`  数据载入: equipSets=${r.debug.dataLoadCounts?.equipSets||0} elixirs=${r.debug.dataLoadCounts?.elixirs||0} materials=${r.debug.dataLoadCounts?.materials||0} artifacts=${r.debug.dataLoadCounts?.artifacts||0}`)
        lines.push(`  分配: ${Object.entries(r.debug.alloc).map(([k,v])=>`${k}:${v}`).join(' | ')}`)
        lines.push(`  上限: ${Object.entries(r.debug.limits||{}).map(([k,v])=>`${k}:${v}`).join(' | ')}`)
        lines.push(`  权重原始: ${Object.entries(r.debug.weightsRaw||{}).map(([k,v])=>`${k}:${v}`).join(' | ')}`)
        lines.push(`  实际权重: ${Object.entries(r.debug.weightsAvail||{}).map(([k,v])=>`${k}:${v}`).join(' | ')}`)
        if (r.debug.probKeysSample){
          for (const [ck,arr] of Object.entries(r.debug.probKeysSample)){
            if (!arr || !arr.length) continue
            lines.push(`  概率键样本【${ck}】:`)
            for (const s of arr){
              const suit = s.套装名称 ? `[${s.套装名称}]` : ''
              const part = s.部位 ? `(${s.部位})` : ''
              lines.push(`    - ${s.名称}${suit}${part} -> ${s.keys.join(',')}`)
            }
          }
        }
        if (r.debug.topCandidates && r.debug.topCandidates.length){
          lines.push(`  权重Top:`)
          for (const t of r.debug.topCandidates){
            const suit = t.套装名称 ? `[${t.套装名称}]` : ''
            const part = t.部位 ? `(${t.部位})` : ''
            lines.push(`    - ${t.类别}${suit}${t.名称}${part} 星级:${t.星级||''} 稀有:${t.稀有度||''} w:${t.w.toFixed(6)}`)
          }
        }
        if (r.debug.dungeonInfo){
          lines.push(`  地牢: base=${r.debug.dungeonInfo.baseTimes} max=${r.debug.dungeonInfo.maxTimes} whitelist=${r.debug.dungeonInfo.hasWhitelist?'Y':'N'} range=${r.debug.dungeonInfo.hasRange?'Y':'N'}`)
        }
      }
      const byCat = {}
      for (const it of r.掉落){
        const cat = it.类别
        byCat[cat] = byCat[cat] || []
        const suit = it.套装名称 ? `[${it.套装名称}]` : ''
        const part = it.部位 ? `(${it.部位})` : ''
        let line = `${suit}${it.名称}${part} 星级:${it.星级||''} 稀有:${it.稀有度||''}`
        if (cat === '圣遗物'){
          const mainKeys = ['生命','防御','速度','生命加成百分比','防御加成百分比','攻击','攻击加成百分比','速度加成百分比','速度加成','暴击率','暴击伤害','首领破防百分比','元素伤害加成百分比','幸运加成百分比']
          const main = {}
          for (const k of mainKeys) if (Number(it[k])) main[k]=it[k]
          const mk = Object.keys(main)[0]
          const mv = Object.values(main)[0]
          const isPercent = (key) => /百分比/.test(key) || key === '暴击率' || key === '暴击伤害' || key === '速度加成' || key === '破防加成'
          const fmt = (key, v) => isPercent(key) ? `${(Number(v||0)*100).toFixed(2)}%` : `${Number(v||0).toFixed(2)}`
          const subs = Array.isArray(it['副词条']) ? it['副词条'].map(s => `${s.键}=${fmt(s.键, s.值)}`).join('，') : ''
          const elem = it['元素'] ? ` 元素:${it['元素']}` : ''
          line += ` 主:${mk||'无'}=${mk?fmt(mk,mv):'0.00'}${elem} 副:${subs||'无'}`
        }
        byCat[cat].push(line)
      }
      for (const k of Object.keys(byCat)){
        lines.push(`【${k}】${byCat[k].length}`)
        for (const s of byCat[k]) lines.push(`  - ${s}`)
      }
      if (!r.掉落 || r.掉落.length===0){
        lines.push(`  注意：掉落为空，可能该层无可用候选或权重为0，请检查数据来源层名与概率键`)
      }
    }
    await this.e.reply(lines.join('\n'))
  }

  async preview(){
    const m = this.e.msg.match(/^#修仙测试预览(.*)$/)
    const { source, layer, times } = this.parseArgs(m ? m[1] : '')
    const text = await DropPreview.preview({ source, layer, times })
    await this.e.reply(text)
  }
}
